using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Windows.Forms;

using GSN.Config;

namespace GSN.Rules
{
    /// <summary>
    /// represents a rule for forcing GSN to work only on specificed times.
    /// </summary>
    class AllowedTimeRule : IGenRule
    {
        private TimeSpan? fromTime = null;
        private TimeSpan? toTime = null;

        public bool showConfigDialog(IConfigurator configurator)
        {
            if (fromTime.HasValue)
                configurator.setItemString(fromTime.Value.ToString(), "From");

            if (toTime.HasValue)
                configurator.setItemString(toTime.Value.ToString(), "To");

            if (configurator.show())
            {
                fromTime = TimeSpan.Parse(configurator.getItemString("From"));
                toTime = TimeSpan.Parse(configurator.getItemString("To"));

                return true;
            }

            return false;
        }

        public string getName() { return "Allowed Time Rule"; }
        public string getDescription() { return "Define when to allow GSN to send SMSes."; }

        public void load(XmlNode node)
        {
            XmlNode fromNode = node.SelectSingleNode("From");
            XmlNode toNode = node.SelectSingleNode("To");

            if (fromNode == null || toNode == null)
                throw new Exception("Error Loading Rule Xml");

            fromTime = TimeSpan.Parse(fromNode.InnerText);
            toTime = TimeSpan.Parse(toNode.InnerText);

            /*fromTime = DateTime.ParseExact(fromNode.InnerText, "HH:mm",
                System.Globalization.CultureInfo.CurrentCulture);

            toTime = DateTime.ParseExact(toNode.InnerText, "HH:mm",
                System.Globalization.CultureInfo.CurrentCulture);*/

        }

        public void save(XmlWriter w)
        {
            w.WriteStartElement("Rule");

            w.WriteElementString("Type", this.GetType().Name);
            w.WriteElementString("From", fromTime.Value.ToString());
            w.WriteElementString("To", toTime.Value.ToString());

            w.WriteEndElement();
        }

        public bool apply()
        {            
            if (!fromTime.HasValue || !toTime.HasValue)
                return false;

            Logger.log("AllowedTimeRule: Applying : From: {0} To: {1}", fromTime, toTime);

            DateTime dtNow = DateTime.Now;

            DateTime dtFromTime = (dtNow - dtNow.TimeOfDay) + fromTime.Value;
            DateTime dtToTime = (dtNow - dtNow.TimeOfDay) + toTime.Value;

            Logger.log("AllowedTimeRule: FromTime: {0} ToTime: {1} Now: {2}", 
                dtFromTime.ToString(), dtToTime.ToString(), dtNow.ToString());

            if (dtFromTime <= dtNow)
            {
                if (toTime < fromTime) // means next day
                    dtToTime = dtToTime.AddDays(1);

                if (dtNow <= dtToTime)
                    return true;
            }
            else
            {
                if (toTime < fromTime)
                {
                    dtFromTime = dtFromTime.AddDays(-1);

                    if (dtFromTime <= dtNow && dtNow <= dtToTime)
                        return true;
                }
            }            

            return false;
        }

        public string getConfiguratorTypeName()
        {
            return "GSNConf.Rules.AllowedTimeRuleConfigurator";
        }

    }
}
